// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Online.h"
#include "GameFramework/GameSession.h"
#include "NetworkGameSession.generated.h"

struct FNetworkSessionParams
{
	/** Name of session settings are stored with */
	FName SessionName;
	/** LAN Match */
	bool bIsLAN;
	/** Presence enabled session */
	bool bIsPresence;
	/** Id of player initiating lobby */
	TSharedPtr<const FUniqueNetId> UserId;
	/** Current search result choice to join */
	int32 BestSessionIdx;

	FNetworkSessionParams() : SessionName(NAME_None), bIsLAN(false), bIsPresence(false), BestSessionIdx(0) { }
};


class FNetworkSessionSettings;
class FNetworkSearchSettings;
UCLASS()
class MISCELLANEOUSPROJECT_API ANetworkGameSession : public AGameSession
{
	GENERATED_UCLASS_BODY()

protected:
	// 创建Session
	// FOnCreateSessionComplete OnCreateSessionComplete;
	DECLARE_EVENT_TwoParams(ANetworkGameSession, FOnCreatePresenceSessionComplete, FName, bool);
	FOnCreatePresenceSessionComplete CreatePresenceSessionCompleteEvent;
	FDelegateHandle OnCreateSessionCompleteDelegateHandle;
	FOnCreateSessionCompleteDelegate OnCreateSessionCompleteDelegate;
	virtual void OnCreateSessionComplete(FName SessionName, bool bWasSuccessful);

	// 开始session
	DECLARE_EVENT_TwoParams(ANetworkGameSession, FOnStartSessionComplete, FName, bool);
	FOnStartSessionComplete StartSessionCompleteEvent;
	FDelegateHandle OnStartSessionCompleteDelegateHandle;
	FOnStartSessionCompleteDelegate OnStartSessionCompleteDelegate;
	virtual void OnStartSessionsComplete(FName InSessionName, bool bWasSuccessful);

	// 更新Session
	DECLARE_EVENT_TwoParams(ANetworkGameSession, FOnUpdateSessionComplete, FName, bool);
	FOnUpdateSessionComplete UpdateSessionCompleteEvent;
	FDelegateHandle OnUpdateSessionCompleteDelegateHandle;
	FOnStartSessionCompleteDelegate OnUpdateSessionCompleteDelegate;
	virtual void OnUpdateSessionsComplete(FName InSessionName, bool bWasSuccessful);

	// 查找session
	DECLARE_EVENT_OneParam(ANetworkGameSession, FOnFindSessionsComplete, bool);
	FOnFindSessionsComplete FindSessionsCompleteEvent;
	FDelegateHandle OnFindSessionCompleteDelegateHandle;
	FOnFindSessionsCompleteDelegate OnFindSessionsCompleteDelegate;
	virtual void OnFindSessionComplete(bool bWasSuccessful);

	// 加入Session
	DECLARE_EVENT_OneParam(ANetworkGameSession, FOnJoinSessionComplete, EOnJoinSessionCompleteResult::Type);
	FOnJoinSessionComplete JoinSessionCompleteEvent;
	FDelegateHandle OnJoinSessionCompleteDelegateHandle;
	FOnJoinSessionCompleteDelegate OnJoinSessionCompleteDelegate;
	virtual void OnJoinSessionsComplete(FName InSessionName, EOnJoinSessionCompleteResult::Type Result);

	// 销毁Session
	// DECLARE_EVENT_TwoParams(ANetworkGameSession, FOnDestroySessionComplete, FName, bool);
	// FOnDestroySessionComplete DestroySessionCompleteEvent;
	// FDelegateHandle OnDestroySessionCompleteDelegateHandle;
	// FOnDestroySessionCompleteDelegate OnDestroySessionCompleteDelegate;
	// virtual void OnDestroySessionComplete(FName InSessionName, bool bWasSuccessful);

private:
	void DebugMessage(FString Message);

	TSharedPtr<FNetworkSessionSettings> HostSetting;
	TSharedPtr<FNetworkSearchSettings> SearchSettings;
	FNetworkSessionParams CurrentSessionParams;

public:
	// 创建Session
	bool HostSession(TSharedPtr<const FUniqueNetId> UserId, FName SessionName, const FString& GameType, const FString& MapName, bool bIsLAN, bool bIsPresence, int32 MaxNumPlayers);
	bool HostSession(const TSharedPtr<const FUniqueNetId> UserId, const FName SessionName, const FOnlineSessionSettings& SessionSettings);
	FOnCreatePresenceSessionComplete& OnCreatePresenceSessionComplete() { return CreatePresenceSessionCompleteEvent; }

	// 开始Session
	virtual void HandleMatchHasStarted() override;

	// 查找session
	void FindSession(TSharedPtr<const FUniqueNetId> UserId, FName InSessionName, bool bIsLAN, bool bIsPresence);
	FOnFindSessionsComplete& OnFindSessionsComplete() { return FindSessionsCompleteEvent; }

	// 更新Session
	void UpdateSession(FName InSessionName, TSharedPtr<FNetworkSessionSettings> InHostSession);
	FOnUpdateSessionComplete& OnUpdateSessionsComplete() { return UpdateSessionCompleteEvent; }
	
	// 加入Session
	bool JoinSession(TSharedPtr<const FUniqueNetId> UserId, FName SessionName, int32 SessionIndexInSearchResults);
	bool JoinSession(TSharedPtr<const FUniqueNetId> UserId, FName SessionName, const FOnlineSessionSearchResult& SearchResult);
	FOnJoinSessionComplete& OnJoinSessionComplete() { return JoinSessionCompleteEvent; }

	// 销毁Session
	virtual void HandleMatchHasEnded() override;

	// 获取找到的Session
	const TArray<FOnlineSessionSearchResult>& GetSearchSessionResult() const;
	const EOnlineAsyncTaskState::Type GetSearchSessionStatus() const;
};
